package com.guaoran.distributed.netty.chat.server.handler;

import com.sun.org.apache.xalan.internal.lib.ExsltBase;
import io.netty.channel.*;
import io.netty.handler.codec.http.*;
import org.apache.log4j.Logger;

import java.io.File;
import java.io.RandomAccessFile;
import java.net.URISyntaxException;
import java.net.URL;

/**
 * @Author gucheng
 * @Description http 协议处理器
 * 2019-04-19 17:36
 */
public class HttpHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
    private Logger log = Logger.getLogger(this.getClass());
    private final String webroot = "webroot";
    //获取class路径
    private URL baseURL = HttpHandler.class.getProtectionDomain().getCodeSource().getLocation();

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, FullHttpRequest fullHttpRequest) throws Exception {
        String uri = fullHttpRequest.getUri();
        RandomAccessFile file;
        try {
            String page = uri.equals("/") ? "chat.html" : uri;
            file = new RandomAccessFile(getResource(page),"r");
        }catch (Exception e){
            channelHandlerContext.fireChannelRead(fullHttpRequest.retain());
            return;
        }

        HttpResponse response = new DefaultHttpResponse(fullHttpRequest.getProtocolVersion(), HttpResponseStatus.OK);
        String contextType = "text/html;";
        if(uri.endsWith(".css")){
            contextType = "text/css;";
        }else if(uri.endsWith(".js")){
            contextType = "text/javascript;";
        }else if(uri.toLowerCase().matches("(jpg|png|gif)$")){
            String ext = uri.substring(uri.lastIndexOf("."));
            contextType = "image/" + ext;
        }
        response.headers().set(HttpHeaders.Names.CONTENT_TYPE, contextType + "charset=utf-8;");
        boolean keepAlive = HttpHeaders.isKeepAlive(fullHttpRequest);

        if (keepAlive) {
            response.headers().set(HttpHeaders.Names.CONTENT_LENGTH, file.length());
            response.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
        }
        channelHandlerContext.write(response);

        channelHandlerContext.write(new DefaultFileRegion(file.getChannel(), 0, file.length()));

        ChannelFuture future = channelHandlerContext.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
        if (!keepAlive) {
            future.addListener(ChannelFutureListener.CLOSE);
        }

        file.close();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        Channel client = ctx.channel();
        log.error("Client:"+client.remoteAddress()+"异常");
        // 当出现异常就关闭连接
        cause.printStackTrace();
        ctx.close();
    }

    private File getResource(String fileName) throws Exception {
        String path = baseURL.toURI() + webroot +"/" + fileName;
        path = !path.contains("file:")?path:path.substring(5);
        path = path.replaceAll("//","/");
        return new File(path);
    }
}
